#include "Namespace.h"
#include "Class.h"

namespace FunctionViewer {
	void Namespace::Init(Program* v_program, char* name) {
		program = v_program;
		prev = program->last_namespace;
		next = NULL;
		if (prev == NULL) program->first_namespace = this;
		else prev->next = this;
		program->last_namespace = this;

		id = ++ program->namespace_counter;

		namespace_counter = 0;
		namespacecount = 0;
		first = NULL;
		last = NULL;
		current = NULL;

		class_counter = 0;
		classcount = 0;
		first_class = NULL;
		last_class = NULL;
		current_class = NULL;

		nname = name;
	}

	void Namespace::DeInit() {
		while (first_class != NULL) DestroyClass(first_class);
		//Remove from list.
		if (prev == NULL) program->first_namespace = next;
		else prev->next = next;
		if (next == NULL) program->last_namespace = prev;
		else next->prev = prev;
		if (program->current_namespace == this) program->current_namespace = NULL;
	}

	Namespace* Namespace::CreateInNamespace(Namespace* _namespace, char* name) {
		Namespace* f_namespace;

		//allocate memory.
		f_namespace = (Namespace*)(malloc(sizeof(Namespace)));
		if (f_namespace == NULL) {
			printf("Memory allocation failed! Could not allocate memory for namespace!"); std::cout << std::endl;
			return NULL;
		}

		f_namespace->v_namespace = _namespace;
		f_namespace->prev = _namespace->last;
		f_namespace->next = NULL;
		if (f_namespace->prev==NULL) _namespace->first = f_namespace;
		else f_namespace->prev->next = f_namespace;
		_namespace->last = f_namespace;

		f_namespace->id = ++_namespace->namespace_counter;

		f_namespace->class_counter = 0;
		f_namespace->classcount = 0;
		f_namespace->first_class = NULL;
		f_namespace->last_class = NULL;
		f_namespace->current_class = NULL;

		f_namespace->nname = name;

		return f_namespace;
	}

	Class* Namespace::CreateClass(char* v_name) {
		Class* v_class = AllocateClass();
		if (v_class == NULL) return NULL;
		v_class->Init(this, ++class_counter, v_name);

		return v_class;
	}

	void Namespace::DestroyClass(Class* v_class) {
		v_class->DeInit();
		free(v_class);
	}

	Class* Namespace::AllocateClass() {
		Class *v_class = (Class*)(malloc(sizeof(Class)));
		if (v_class == NULL) {
			printf("Could not create class in namespace %lu, memory allocation failed.", id);
			return NULL;
		}
		return v_class;
	}
}